//////////////////////////////////////////////////////////////////////////
// List::Node
//////////////////////////////////////////////////////////////////////////
template<class T>
List<T>::Node::Node( void ):element(),next(null){}

template<class T>
List<T>::Node::Node( const T& $copyFrom ):element($copyFrom),next(null){}

template<class T>
List<T>::Node::Node( const  Node& $copyFrom )
{
	next    = $copyFrom.next;
	element = $copyFrom.element;
}

template<class T>
typename List<T>::Node& List<T>::Node::operator = (const  Node& $rsh)
{
	next    = $rsh.next;
	element = $rsh.element;
	return *this;
}

template<class T>
bool List<T>::Node::operator == (const  Node& $rsh) const
{
	return next == $rsh.next && element == $rsh.element ? true : false;
}

template<class T>
List<T>::Node::~Node( void ){}

template<class T>
 void List<T>::Node::SetElement( const T& $element )
{
	element = $element;
}

template<class T>
 T& List<T>::Node::GetElement( void )
{
	return this->element;
}

template<class T>
 const T& List<T>::Node::GetElement( void ) const
{
	return this->element
}

template<class T>
typename List<T>::Node* List<T>::Node::GetNext( void )
{
	return this->next;
}

template<class T>
typename const List<T>::Node* List<T>::Node::GetNext( void ) const
{
	return this->next;
}

template<class T>
typename List<T>::Node* List<T>::Node::AddNode( const Node& $element )
{
	this->next = new Node($element);
	return this->next;
}

//////////////////////////////////////////////////////////////////////////
// List
//////////////////////////////////////////////////////////////////////////

template<class T>
List<T>::List( void ):head(null),tail(null){}

template<class T>
List<T>::List( const List<T>& $copyFrom )
{
	*this = $copyFrom;
}

template<class T>
List<T>::List( const  Node& $head )
{
	assert(head);
	head = tail = &$head;
}

template<class T>
List<T>::~List( void )
{
	Node* p = head;
	while(p)
	{
		head = head->next;
		SAFE_DELETE(p);
		p = head;		
	}
}

template<class T>
List<T>& List<T>::operator = ( const List<T>& $rsh )
{
	// copy all of it to do..
	head = $rsh.head;
	tail = $rsh.tail;
	return *this;
}

template<class T>
int List<T>::Size( void ) const
{
	int size   = 0;
	Node* next = Head();
	while(next)
	{
		next = next->GetNext();
		++size;
	}
	return size;
}

template<class T>
typename List<T>::Node* List<T>::Head( void ) const
{
	return head;
}

template<class T>
typename List<T>::Node* List<T>::Tail( void ) const
{
	return tail;
}

template<class T>
void List<T>::Append( const Node& $element )
{
	if( !head ) 
	{
		assert( head == tail );
		head = new Node($element);
		tail = head;
	}
	else
	{
		tail->AddNode($element); 
		tail = tail->GetNext();
	}
}

template<class T>
typename List<T>::Node* List<T>::Insert ( Node* pos, const Node& $element )
{
	assert(pos);
	if(!pos)
		return null;
	if( pos == tail )
	{
		Append( $element );
		return tail;
	}
	else
	{
		Node* oldNode = pos->GetNext();
		Node* newNode = pos->AddNode($element);
		newNode->next = oldNode;
		return newNode;
	}
}